package com.open.httpauto;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.open.httpauto.http.Http;
import com.open.httpauto.http.ParameterBase;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * http 请求控制
 */
@SuperBuilder
@AllArgsConstructor
@NoArgsConstructor
public class HttpRequest<T extends ParameterBase> implements IHttpHandler<T> {

    private List<Http> httpList;
    private Http http;
    private T t;
    private Class<? extends ParameterBase> rClazz;

    /**
     * 通过 yml 名称 自动扫描 yml 配置，并实现 http 数据的
     * 读取，将读取后的对象 再完成请求
     *
     * @param httpId yaml中对应的 httpId
     * @param t      泛型自定义数据 需要继承 {@link ParameterBase}
     * @param rClazz 返回要求的类型 class
     * @return HttpRequest
     */
    @Override
    public HttpRequest request(String httpId, T t, Class<? extends ParameterBase> rClazz) {
        if (!CollectionUtil.isEmpty(httpList)) {
            Map<String, Http> map = httpList.stream().collect(Collectors.toMap(Http::getId, Function.identity()));
            this.http = map.get(httpId);
        } else {
            this.http = HttpYamlHandler.Instance.getHttp(httpId);
        }
        this.t = t;
        this.rClazz = rClazz;
        return this;
    }

    /**
     * 请求
     * 请求时需要传入 返回类型 class，自动
     * 转化返回结果
     *
     * @param http   http全局信息 通过yaml转化而来
     * @param t      请求泛型扩展参数，需要继承 {@link ParameterBase}
     * @param rClazz 返回要求的类型 class
     * @param <R>    泛型返回类型
     * @return R
     */
    @Override
    public <R> R request(Http http, T t, Class<? extends ParameterBase> rClazz) {
        JSONObject jsonObject = JSON.parseObject(JSON.toJSONString(t));
        String host = http.getHost();
        String method = http.getMethod();
        String contentType = http.getHeader().getContentType();
        String param = ConvertHandler.Instance.convertRequest(http, jsonObject);

        HttpResponse httpResponse = this.request(host, method, contentType, param);

        String responseText = httpResponse.body();
        JSONObject responseJsonObject = ConvertHandler.Instance.convertResponse(responseText, http.getResponse());
        if (CollectionUtil.isEmpty(responseJsonObject)) {
            return null;
        }

        //获取泛型 R class 并通过 fastjson 反序列化
        R r = (R) responseJsonObject.to(rClazz);
        return r;
    }

    @Override
    public <R> R preHandle(Http http, T t, Class<? extends ParameterBase> rClazz) {
        return null;
    }

    @Override
    public <R> R afterCompletion(Http http, T t, Class<? extends ParameterBase> rClazz) {
        return null;
    }

    /**
     * 执行请求
     * 此方法会处理前置，后置，业务处理等业务
     * 参数会传递向下进行执行
     * 1.before请求处理
     * 2.请求处理
     * 3.after处理
     *
     * @return 响应结果
     */
    @Override
    public <R> R execute() {
//        R preHandle = this.preHandle();
        R r = this.request(http, t, rClazz);
//        R afterCompletion = this.afterCompletion(,request);
        return r;
    }
}
